/*->c.record */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <time.h>

#include "h.os"
#include "h.wimp"



#include "h.wos"
#include "h.main"
#include "h.ram"
#include "h.mym"
#include "h.pr"
#include "h.key"

#include "h.xext"

#include "h.file"
#include "h.script"
#include "h.serial"

#include "h.record"



/***************************************************************************/
/*

 Code to handle script recording

*/
/*****************************************************************************/


#define WIDTH 80



                                            /* nothing */
#define RECORDBASE  0
                                            /* in a kprints statement */
#define RECORDKEY   1
#define RECORDPAUSE 2
#define RECORDVDU   3




int    recordflag=0;                        /* 1= we are spooling stuff */
FILE * recordfp=NULL;                       /* pointer to spool file */

int    recordstate;



int     recordlen;

int     recordtk;           /* time of last key press */
int     recordtv;           /* time of entry to vdu state */
int     recordp;            /* time of entry to pause state */
int     recordlv;           /* time of last vdu */

int     rvdulo;
int     rvduhi;

                            /* 2^n-1 */
#define RVMASK 31

char    rvdus[RVMASK+1];


void recordenterkey(void)
{
/* dprintf(0,"record enter key"); */

 fputs("\nkprints(\"",recordfp);
 recordstate=RECORDKEY;
 recordlen=10;
 addzeroevent(RECORDZERO);
}


void recordexitkey(void)
{
 fputs("\");\n",recordfp);
/* dprintf(0,"record exit key"); */

 recordstate=RECORDBASE;
 remzeroevent(RECORDZERO);
}


void recordenterpause(void)
{
/* dprintf(0,"record enter pause"); */

 recordp=clock();
 recordstate=RECORDPAUSE;
 addzeroevent(RECORDZERO);
}


void recordexitpause(void)
{
 int delay=clock()-recordp;

/* dprintf(0,"record exit pause"); */

 if(delay>50) fprintf(recordfp,"pause(%d);\n",delay);
 recordstate=RECORDBASE;
 remzeroevent(RECORDZERO);
}


void recordentervdu(void)
{
/* dprintf(0,"record enter vdu"); */

 recordtv=clock();
 rvdulo=rvduhi=0;
 recordstate=RECORDVDU;
 addzeroevent(RECORDZERO);
}


void recordexitvdu(void)
{
 char   vdus[256];
 char * p;

/* dprintf(0,"record exit vdu rvdulo=%d rvduhi=%d",rvdulo,rvduhi); */

 p=vdus;
 while(rvdulo<rvduhi) p=uncode(p,rvdus[rvdulo++ & RVMASK]);

 fprintf(recordfp,"getprompt(\"%s\",%d);\n",vdus,clock()-recordtv+500);
 recordstate=RECORDBASE;
 remzeroevent(RECORDZERO);
}



void recordgobase(void)
{
 if(recordstate==RECORDKEY)   recordexitkey();
 else
 if(recordstate==RECORDVDU)   recordexitvdu();
 else
 if(recordstate==RECORDPAUSE) recordexitpause();
}



void recordkeypress(char * string)
{            
 if(online)
 {
  if(recordstate!=RECORDKEY)
  {
   recordgobase();
   recordenterkey();
  }

  fputs(string,recordfp);
  recordlen+=strlen(string);
  recordtk=clock();

  if(recordlen>WIDTH-3-8) recordexitkey();
 }
}


void recordvdu(int byte)
{
 if(byte!=-1 && online)
 {
/*  dprintf(0,"record vdu"); */

  if(recordstate==RECORDPAUSE || recordstate==RECORDBASE)
  {
   recordgobase();
   recordentervdu();
  }

  if(recordstate==RECORDVDU)
  {
   rvdus[rvduhi++ & RVMASK]=byte;
   if((rvduhi-rvdulo)>=RVMASK) rvdulo++;
   recordlv=clock();
  }

/*  dprintf(0,"record xvdu"); */
 }
}


void recordzero(void)
{
 if(!online) recordgobase();
 else
 if(recordstate==RECORDKEY)
 {
  if((zerotime-recordtk)>150)
  {
   recordgobase();
   recordenterpause();
  }
 }
 else
 if(recordstate==RECORDVDU)
 {
  if((zerotime-recordlv)>300)
  {
   recordgobase();
   recordenterpause();
  }
 }
}



void recordclose(void)                 /* close spool file */
{
 recordgobase();

 fputs("}\n\n",recordfp);

 fclose(recordfp);
 recordfp=NULL;
 recordflag=0;
}




int openrecordfile(char * filename)  /* open spool file */
{
 FILE * fp;

 if(pendingramwrite()) return(0);

 createfile(filename,0,SCRIPT);
 if((fp=fopen(filename,"wb"))==NULL) return(0);

 if(recordfp!=NULL) recordclose();

 recordfp=fp;
 recordflag=1;

 recordstate=RECORDBASE;
 hsystdheader(fp,leaf(filename));
 fputs("void main(void)\n{\n",recordfp);

 return(1);
}




void recordtoggle(void)                /* toggle spool state */
{
 if(recordfp!=NULL)
 {
  recordgobase();
  recordflag^=1;
 }
}




void decodemisc(int m1,int m2)
{
 switch(m1)
 {

  case 0:         /* save config */
         break;

  case 1:
         savedefaultconfig();
         break;

  case 2:        /* open record */
         break;

  case 3:        /* record toggle */
         recordtoggle();
         break;

  case 4:        /* close record */
         recordclose();
         break;

  case 5:        /* stop script */
         zruns=0;
         break;

  case 6:
         decodeusermacro(m2);
         break;
 }
}


void setpopmisc(void)
{
 unshadest(misc_menu,3,recordfp!=NULL);
 unshadest(misc_menu,4,recordfp!=NULL);
 tickst(misc_menu,3,recordflag);
 unshadest(misc_menu,5,zlevel);
 unshadest(misc_menu,6,usermacros());
}



